﻿using Haidou.Wpf.Util;
using IWshRuntimeLibrary;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using HandyControl.Controls;

namespace Haidou.Wpf.UI.Util
{
	public static class App_Startup
	{
		#region Properties

		public static NotifyIcon NotifyIcon { get; set; }

		/// <summary>
		/// UI的Commands  ---命令
		/// </summary>



		private static readonly List<Exception> _exceptionList = new();
		private static readonly object _lock = new();


		/// <summary>
		/// 快捷方式名称-任意自定义
		/// </summary>
		private const string QuickName = "Haidou.Desktop";

		/// <summary>
		/// 自动获取系统自动启动目录
		/// </summary>
		public static string systemStartPath => Environment.GetFolderPath(Environment.SpecialFolder.Startup);

		/// <summary>
		/// 自动获取程序完整路径
		/// </summary>
		public static string appAllPath => Process.GetCurrentProcess().MainModule.FileName;


		#endregion




		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, uint dwFlags);

		public static void InitChrome()
		{

			try
			{

				string cefpath = GetCefPath();
				LoadLibraryEx(Path.Combine(cefpath, @"libcef.dll"), IntPtr.Zero, 0x00000008);

				InitCef(cefpath);


			}
			catch (Exception ex)
			{
				LogWriter.Log(ex, "App_Startup.InitChrome");

			}

		}
		public static string GetCefPath()
		{
			string? basePath = AppDomain.CurrentDomain.BaseDirectory;
			string path = string.Empty;
			int i = 0;
			do
			{
				path = Path.Combine(basePath, "Haidou.Desktop Cef");
				if (Directory.Exists(path))
				{
					return path;
				}
				basePath = Path.GetDirectoryName(basePath);
			} while (i++ < 3);
			return null;
		}


		/// <summary>
		/// cef Initialize
		/// </summary>
		public static void InitCef(string cefpath)
		{

			//try
			//{

			//	CefSettings settings = new CefSettings();

			//	settings.CefCommandLineArgs.Add("disable-gpu", "1");
			//	settings.CefCommandLineArgs.Add("--ignore-urlfetcher-cert-requests", "1");
			//	settings.CefCommandLineArgs.Add("--ignore-certificate-errors", "1");
			//	settings.CefCommandLineArgs.Add("--disable-web-security", "1");//关闭同源策略,允许跨域

			//	settings.CefCommandLineArgs.Add("enable-system-flash", "1");  //flash
			//	settings.CefCommandLineArgs.Add("enable-speech-input", "1");  //语音输入


			//	settings.CefCommandLineArgs.Add("enable-begin-frame-scheduling", "1");
			//	settings.CefCommandLineArgs.Add("allow-running-insecure-content");

			//	settings.CefCommandLineArgs["autoplay-policy"] = "no-user-gesture-required";
			//	settings.CefCommandLineArgs.Add("enable-media-stream");//媒体流
			//	settings.CefCommandLineArgs.Add("disable-direct-write", "1");

			//	settings.CachePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"caches");


			//	settings.LocalesDirPath = Path.Combine(cefpath, @"locales");
			//	settings.ResourcesDirPath = Path.Combine(cefpath, "");


			//	settings.BrowserSubprocessPath = Path.Combine(cefpath, @"Haidou.Desktop Browser.exe");

			//	settings.LogSeverity = LogSeverity.Disable;


			//	settings.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36";
			//	Cef.Initialize(settings);
			//	//Cef.Initialize(settings, performDependencyCheck: false, browserProcessHandler: null);

			//	//Cef.EnableHighDPISupport();

			//}
			//catch (Exception ex)
			//{
			//	LogWriter.Log("err", "InitCef", ex.Message);


			//}

		}




		[DllImport("shfolder.dll", CharSet = CharSet.Auto)]
		private static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwFlags, StringBuilder lpszPath);
		private const int MAX_PATH = 260;
		private const int CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019;
		public static string GetAllUsersDesktopFolderPath()
		{
			StringBuilder sbPath = new(MAX_PATH);
			SHGetFolderPath(IntPtr.Zero, CSIDL_COMMON_DESKTOPDIRECTORY, IntPtr.Zero, 0, sbPath);
			return sbPath.ToString();
		}

		/// <summary>
		/// 生成快捷方式
		/// </summary>
		public static void UpdateShortcutIco()
		{
			try
			{
				

					//RemoveDuplicateShortcutsAll("");
					//先删除所有的，重新创建现在的
					RemoveDuplicateShortcutsAll("");


					string initialSource = Path.Combine(GetAllUsersDesktopFolderPath(), @".lnk");

					if (!System.IO.File.Exists(initialSource))
					{
						initialSource = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), @".lnk");
					}

					WshShell shell = new();
					IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(initialSource);//获取快捷方式对象
					string targetPath = shortcut.TargetPath;//读取右键快捷方式的目标信息
					string workingDirectory = shortcut.WorkingDirectory;//读取右键快捷方式的起始位置信息
					int windowStyle = shortcut.WindowStyle;//读取右键快捷方式的运行方式信息
					string description = shortcut.Description;//读取右键快捷方式的备注信息
					string iconLocation = shortcut.IconLocation;//读取 快捷方式的图标信息

					if (!targetPath.Contains("Haidou.Desktop"))
					{
						shortcut.TargetPath = System.Windows.Forms.Application.ExecutablePath;
						shortcut.Save();
					}




				///改名了 去掉之前的
				///
				RemoveDuplicateShortcutsAll("");

			}
			catch (DllNotFoundException e)
			{
				LogWriter.Log(e, "DLL not found.");
			}
			catch (EntryPointNotFoundException e)
			{
				LogWriter.Log(e, "Entry point not found in the DLL.");
			}
			catch (BadImageFormatException e)
			{
				LogWriter.Log(e, "DLL is invalid for the current platform.");
			}
			catch (Exception e1)
			{
				LogWriter.Log(e1, "UpdateShortcutIco");
			}




		}

		/// <summary>
		/// 删除相同名称的 lnk 只保留一个
		/// </summary>
		/// <param name="shortcutName"></param>
		/// <returns></returns>
		public static bool RemoveDuplicateShortcuts(string shortcutName)
		{
			string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
			string[] shortcutPaths = Directory.GetFiles(desktopPath, $"{shortcutName}.lnk", SearchOption.TopDirectoryOnly);

			string desktopPathPublic = "C:\\Users\\Public\\Desktop";
			string[] shortcutPathsPublic = Directory.GetFiles(desktopPathPublic, $"{shortcutName}.lnk", SearchOption.TopDirectoryOnly);


			if (shortcutPaths.Length > 1)
			{
				foreach (string path in shortcutPaths)
				{
					try
					{
						System.IO.File.Delete(path);
						Debug.WriteLine($"Deleted duplicate shortcut: {path}");
					}
					catch (Exception ex)
					{
						Debug.WriteLine($"Failed to delete shortcut {path}: {ex.Message}");
					}
				}
				return true; // 成功删除了至少一个
			}
			else if (shortcutPathsPublic.Length > 1)
			{
				foreach (string path in shortcutPathsPublic)
				{
					try
					{
						System.IO.File.Delete(path);
						Debug.WriteLine($"Deleted duplicate shortcut: {path}");
					}
					catch (Exception ex)
					{
						Debug.WriteLine($"Failed to delete shortcut {path}: {ex.Message}");
					}
				}
				return true; // 成功删除了至少一个
			}

			else
			{
				Debug.WriteLine($"No duplicate shortcuts found with name '{shortcutName}'.lnk");
				return false;
			}
		}


		/// <summary>
		/// 删除相同名称的 lnk 只保留一个
		/// </summary>
		/// <param name="shortcutName"></param>
		/// <returns></returns>
		public static bool RemoveDuplicateShortcutsAll(string shortcutName)
		{

			string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);


			string[] shortcutPaths = Directory.GetFiles(desktopPath, $"{shortcutName}.lnk", SearchOption.TopDirectoryOnly);

			string desktopPathPublic = "C:\\Users\\Public\\Desktop";
			string[] shortcutPathsPublic = Directory.GetFiles(desktopPathPublic, $"{shortcutName}.lnk", SearchOption.TopDirectoryOnly);

			if (shortcutPaths.Length > 0)
			{
				foreach (string path in shortcutPaths)
				{
					try
					{
						System.IO.File.Delete(path);
						//Debug.WriteLine($"Deleted duplicate shortcut: {path}");
					}
					catch (Exception)
					{
						//Debug.WriteLine($"Failed to delete shortcut {path}: {ex.Message}");
					}
				}
				return true; // 成功删除了至少一个
			}

			else if (shortcutPathsPublic.Length > 0)
			{
				foreach (string path in shortcutPathsPublic)
				{
					try
					{
						System.IO.File.Delete(path);
						//Debug.WriteLine($"Deleted duplicate shortcut: {path}");
					}
					catch (Exception)
					{
						//Debug.WriteLine($"Failed to delete shortcut {path}: {ex.Message}");
					}
				}
				return true; // 成功删除了至少一个
			}
			else
			{
				//Debug.WriteLine($"No duplicate shortcuts found with name '{shortcutName}'.lnk");
				return false;
			}
		}




		public static void ShowException(Exception exception)
		{
			lock (_lock)
			{
				//避免显示已经显示的异常。
				if (_exceptionList.Any(a => a.Message == exception.Message))
				{
					return;
				}

				//添加到列表中，这样就不会显示同名的第二个异常。
				_exceptionList.Add(exception);


				Global.Current.Dispatcher.Invoke(() =>
				{
					//if (Global.IsHotFix4055002Installed && exception is XamlParseException && exception.InnerException is TargetInvocationException)
					//{
					//	ExceptionDialog.Ok(exception, "Haidou.Wpf.UI", "渲染视觉效果时出错", exception.Message);
					//}
					//else
					//{
					//	ExceptionDialog.Ok(exception, "Haidou.Wpf.UI", "未处理异常情况", exception.Message);
					//}
				});

				//通过移除该异常，可以在以后显示相同的异常。
				_exceptionList.Remove(exception);
			}
		}





		/// <summary>
		/// 显示 置顶当前应用
		/// </summary>
		/// <param name="e"></param>
		/// <returns></returns>
		public static bool DisplayApp(StartupEventArgs e)
		{
			try
			{

				if (e.Args == null || e.Args.Length == 0)
				{
					IntPtr ptr = HasWindows("");
					if (ptr != IntPtr.Zero)
					{
						Win32.ShowWindowAsync(ptr, 1);  //调用api函数，正常显示窗口
						Win32.SetForegroundWindow(ptr); //将窗口放置最前端
						return false;
					}
				}
				return true;

			}
			catch (Exception ex)
			{
				LogWriter.Log(ex, "DisplayApp");
				return true;

			}

		}
		/// <summary>
		/// 显示 置顶当前应用
		/// </summary>
		/// <param name="e"></param>
		/// <returns></returns>
		public static bool DisplayUIApp()
		{

			try
			{

				IntPtr ptr = HasWindows("");
				if (ptr != IntPtr.Zero)
				{
					Win32.ShowWindowAsync(ptr, 1);  //调用api函数，正常显示窗口
					Win32.SetForegroundWindow(ptr); //将窗口放置最前端
					return false;
				}

				return true;

			}
			catch (Exception ex)
			{

				LogWriter.Log(ex, "DisplayUIApp");
				return true;


			}
		}

	


		/// <summary>
		/// 关闭 
		/// </summary>
		/// <returns></returns>
		public static bool CloseAITabTip()
		{

			try
			{
				Process[] process = Process.GetProcessesByName("TabTip");

				foreach (Process item in process)
				{
					// 确保找到了进程
					if (item != null)
					{
						// 尝试关闭进程
						try
						{
							item.Kill();
							Debug.WriteLine("进程已关闭。");
							Debug.Write("进程已关闭");
						}
						catch (Exception ex)
						{
							Debug.WriteLine("无法关闭进程： " + ex.Message);
						}
					}

				}
				return false;

			}
			catch (Exception ex)
			{

				LogWriter.Log(ex, "CloseAITabTip");
				return false;

			}
		}





		/// <summary>
		/// 显示 置顶当前应用
		/// </summary>
		/// <param name="e"></param>
		/// <returns></returns>
		public static bool DisplayApp()
		{
			try
			{


				IntPtr ptr = HasWindows("");
				if (ptr != IntPtr.Zero)
				{
					Win32.ShowWindowAsync(ptr, 1);  //调用api函数，正常显示窗口
					Win32.SetForegroundWindow(ptr); //将窗口放置最前端
					return false;
				}
			}
			catch (Exception ex)
			{

				LogWriter.Log(" DisplayApp", ex.Message);
			}
			return true;
		}


		/// <summary>
		/// 显示 置顶当前应用
		/// </summary>
		/// <param name="e"></param>
		/// <returns></returns>
		public static bool DisplayAppDelineationTranslation()
		{
			try
			{



				IntPtr ptr = HasWindows("");
				if (ptr != IntPtr.Zero)
				{
					Debug.WriteLine("找到了");
					Win32.ShowWindowAsync(ptr, 1);  //调用api函数，正常显示窗口
					Win32.SetForegroundWindow(ptr); //将窗口放置最前端
					return false;
				}
				else
				{
					Debug.WriteLine("没z到了");

				}

				return true;
			}
			catch (Exception ex)
			{

				LogWriter.Log(" DisplayAppDelineationTranslation", ex.Message);
				return true;

			}
		}



		/// <summary>
		/// 显示 置顶当前应用
		/// </summary>
		/// <param name="e"></param>
		/// <returns></returns>
		public static bool DisplayAppRecordingStatusShou()
		{

			IntPtr ptr = HasWindows("");
			if (ptr != IntPtr.Zero)
			{
				Debug.WriteLine("找到了");
				Win32.ShowWindowAsync(ptr, 1);  //调用api函数，正常显示窗口
				Win32.SetForegroundWindow(ptr); //将窗口放置最前端
				return false;
			}
			else
			{
				Debug.WriteLine("没z到了");

			}

			return true;
		}

		/// <summary>
		/// 显示 置顶当前应用
		/// </summary>
		/// <param name="e"></param>
		/// <returns></returns>
		public static bool DisplayAppFloatingWindow()
		{
			try
			{


				IntPtr ptr = HasWindows("语音精灵");
				if (ptr != IntPtr.Zero)
				{
					Debug.WriteLine("找到了");
					Win32.ShowWindowAsync(ptr, 1);  //调用api函数，正常显示窗口
					Win32.SetForegroundWindow(ptr); //将窗口放置最前端
					return false;
				}
				else
				{
					Debug.WriteLine("没z到了");

					return true;
				}
			}
			catch (Exception ex)
			{

				LogWriter.Log(ex, "DisplayAppFloatingWindow");
				return true;

			}
		}






		public static IntPtr HasWindows(String WindowTitle)
		{

			try
			{


				IntPtr desktopPtr = Win32.GetDesktopWindow();
				//2、获得一个子窗口（这通常是一个顶层窗口，当前活动的窗口）
				IntPtr winPtr = Win32.GetWindow(desktopPtr, GetWindowCmd.GW_CHILD);

				//3、循环取得桌面下的所有子窗口
				while (winPtr != IntPtr.Zero)
				{
					//4、继续获取下一个子窗口
					winPtr = Win32.GetWindow(winPtr, GetWindowCmd.GW_HWNDNEXT);
					StringBuilder title = new(1000);
					Win32.GetWindowText(winPtr, title, 1000);

					if (title.ToString().Trim() == WindowTitle)
					{
						return winPtr;
					}

				}
				return IntPtr.Zero;
			}
			catch (Exception ex)
			{
				LogWriter.Log(ex, "HasWindows");
				return IntPtr.Zero;

			}


		}


		/// <summary>
		/// 设置开机自动启动-只需要调用改方法就可以了参数里面的bool变量是控制开机启动的开关的，默认为开启自启启动
		/// </summary>
		/// <param name="onOff">自启开关</param>
		public static void SetMeAutoStart(bool onOff = true)
		{

			try
			{


				if (onOff)//开机启动
				{
					//获取启动路径应用程序快捷方式的路径集合
					List<string> shortcutPaths = GetQuickFromFolder(systemStartPath, appAllPath);
					//存在2个以快捷方式则保留一个快捷方式-避免重复多于
					if (shortcutPaths.Count >= 2)
					{
						for (int i = 1; i < shortcutPaths.Count; i++)
						{
							DeleteFile(shortcutPaths[i]);
						}
					}
					else if (shortcutPaths.Count < 1)//不存在则创建快捷方式
					{
						CreateShortcut(systemStartPath, QuickName, appAllPath, "海豆Desktop");
					}

					using (RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run", true))
					{
						string? url = Process.GetCurrentProcess().MainModule.FileName;
						key.SetValue("Haidou.Desktop", "\"" + url + "\"");
						key.Close();
					}

				}
				else//开机不启动
				{
					//获取启动路径应用程序快捷方式的路径集合
					List<string> shortcutPaths = GetQuickFromFolder(systemStartPath, appAllPath);
					//存在快捷方式则遍历全部删除
					if (shortcutPaths.Count > 0)
					{
						for (int i = 0; i < shortcutPaths.Count; i++)
						{
							DeleteFile(shortcutPaths[i]);
						}
					}

					using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run", true)) // 使用false，因为不需要创建键
					{
						if (key != null && key.GetValue("Haidou.Desktop") != null)
						{
							key.SetValue("Haidou.Desktop", "");
							key.Close();
						}
					}

				}

			}
			catch (Exception ex)
			{
				LogWriter.Log("SetMeAutoStart", ex.Message);
			}

			//创建桌面快捷方式-如果需要可以取消注释
			//CreateDesktopQuick(desktopPath, QuickName, appAllPath);
		}

		/// <summary>
		/// 根据路径删除文件-用于取消自启时从计算机自启目录删除程序的快捷方式
		/// </summary>
		/// <param name="path">路径</param>
		public static void DeleteFile(string path)
		{
			try
			{
				FileAttributes attr = System.IO.File.GetAttributes(path);
				if (attr == FileAttributes.Directory)
				{
					Directory.Delete(path, true);
				}
				else
				{
					System.IO.File.Delete(path);
				}
			}
			catch (Exception ex)
			{
				LogWriter.Log(ex.Message);
			}
		}


		/// <summary>
		/// 获取指定文件夹下指定应用程序的快捷方式路径集合
		/// </summary>
		/// <param name="directory">文件夹</param>
		/// <param name="targetPath">目标应用程序路径</param>
		/// <returns>目标应用程序的快捷方式</returns>
		public static List<string> GetQuickFromFolder(string directory, string targetPath)
		{
			List<string> tempStrs = new();
			tempStrs.Clear();
			string tempStr = null;
			try
			{
				string[] files = Directory.GetFiles(directory, "*.lnk");
				if (files == null || files.Length < 1)
				{
					return tempStrs;
				}
				for (int i = 0; i < files.Length; i++)
				{
					//files[i] = string.Format("{0}\\{1}", directory, files[i]);
					tempStr = GetAppPathFromQuick(files[i]);
					if (tempStr == targetPath)
					{
						tempStrs.Add(files[i]);
					}
				}
				return tempStrs;
			}
			catch (Exception ex)
			{
				LogWriter.Log(ex.Message);
				//tempStrs.Clear();
				return tempStrs;
			}
		}

		/// <summary>
		/// 获取快捷方式的目标文件路径-用于判断是否已经开启了自动启动
		/// </summary>
		/// <param name="shortcutPath"></param>
		/// <returns></returns>
		public static string GetAppPathFromQuick(string shortcutPath)
		{
			try
			{
				//快捷方式文件的路径 = @"d:\Test.lnk";
				if (System.IO.File.Exists(shortcutPath))
				{
					WshShell shell = new();
					IWshShortcut shortct = (IWshShortcut)shell.CreateShortcut(shortcutPath);
					//快捷方式文件指向的路径.Text = 当前快捷方式文件IWshShortcut类.TargetPath;
					//快捷方式文件指向的目标目录.Text = 当前快捷方式文件IWshShortcut类.WorkingDirectory;
					return shortct.TargetPath;
				}
				else
				{
					return "";
				}
			}
			catch (Exception ex)
			{
				LogWriter.Log(ex.Message);
				return "";
			}
		}

		/// <summary>
		///  向目标路径创建指定文件的快捷方式
		/// </summary>
		/// <param name="directory">目标目录</param>
		/// <param name="shortcutName">快捷方式名字</param>
		/// <param name="targetPath">文件完全路径</param>
		/// <param name="description">描述</param>
		/// <param name="iconLocation">图标地址</param>
		/// <returns>成功或失败</returns>
		private static bool CreateShortcut(string directory, string shortcutName, string targetPath, string description = null, string iconLocation = null)
		{
			try
			{
				if (!Directory.Exists(directory))
				{
					Directory.CreateDirectory(directory);                         //目录不存在则创建
				}
				//添加引用 Com 中搜索 Windows Script Host Object Model
				string shortcutPath = Path.Combine(directory, string.Format("{0}.lnk", shortcutName));          //合成路径
				WshShell shell = new();
				IWshShortcut? shortcut = shell.CreateShortcut(shortcutPath) as IWshShortcut;    //创建快捷方式对象
				shortcut.TargetPath = targetPath;                                                               //指定目标路径
				shortcut.WorkingDirectory = Path.GetDirectoryName(targetPath);                                  //设置起始位置
				shortcut.WindowStyle = 1;                                                                       //设置运行方式，默认为常规窗口
				shortcut.Description = description;                                                             //设置备注
				shortcut.IconLocation = string.IsNullOrWhiteSpace(iconLocation) ? targetPath : iconLocation;    //设置图标路径
				shortcut.Save();                                                                                //保存快捷方式
				return true;
			}
			catch (Exception ex)
			{
				string temp = ex.Message;
				temp = "";
				LogWriter.Log(ex.Message);

			}
			return false;
		}





	}
}
